Skip to content

Fix C# generator base model recursion#11008

Merged
live1206 merged 8 commits into
mainfrom
live1206/fix-mtg-model-base-cycles
Jun 23, 2026
Merged

Fix C# generator base model recursion#11008
live1206 merged 8 commits into
mainfrom
live1206/fix-mtg-model-base-cycles

Conversation

@live1206

Copy link
Copy Markdown
Contributor

Fixes C# generator recursion when a customized/base model provider chain cycles through an inheritable system model.

Changes:

  • Make MTG model base-provider traversal cycle-safe for properties, constructor initialization, fields, raw data fields, and full constructor discovery.
  • Make ClientModel MRW serialization base traversal cycle-safe.
  • Make ModelReaderWriter context collection avoid revisiting base model providers.
  • Emit new on explicit response conversion operators from ClientModel when a base model already exposes the same conversion.

Validation:

  • dotnet build packages/http-client-csharp/generator/Microsoft.TypeSpec.Generator.ClientModel/src/Microsoft.TypeSpec.Generator.ClientModel.csproj -v:minimal
  • Consumed locally from azure-sdk-for-net mgmt generator; StorageCache regen completes in ~48s.

Make base model provider traversal cycle-safe across model construction, MRW serialization, and ModelReaderWriter context collection. Also emit explicit response conversion hiding at the ClientModel layer when a base model already exposes the same conversion.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@microsoft-github-policy-service microsoft-github-policy-service Bot added the emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp label Jun 17, 2026
@pkg-pr-new

pkg-pr-new Bot commented Jun 17, 2026

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@typespec/http-client-csharp@11008

commit: bb87f5e

@github-actions

Copy link
Copy Markdown
Contributor

No changes needing a change description found.

@live1206

Copy link
Copy Markdown
Contributor Author

No regen diff in Azure/azure-sdk-for-net#59998

live1206 and others added 5 commits June 22, 2026 02:59
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@live1206 live1206 marked this pull request as ready for review June 22, 2026 03:22
@JoshLove-msft

Copy link
Copy Markdown
Contributor

Review notes (non-blocking)

LGTM overall — correct, well-scoped cycle-safety fix. CI is green and the change is approved. A few minor observations:

  1. BuildConstructorParameters — dropped .Signature != null: The change from BaseModelProvider?.FullConstructor.Signature != null to BaseModelProvider is not null && !HasBaseModelProviderCycle() is safe — ConstructorProvider.Signature is a non-nullable ConstructorSignature, so the old null check only guarded BaseModelProvider. No regression; just flagging since the null-guard removal isn''t obvious from the diff.

  2. Logic duplication: The cycle-safe enumeration now exists in three forms (ModelProvider.EnumerateBaseModelProviders, plus two in MrwSerializationTypeDefinition), and HasBaseModelProviderCycle re-walks the same chain EnumerateBaseModelProviders already guards. Consider consolidating to a single shared helper to avoid drift, though the private/cross-class boundaries make the current split understandable.

  3. No regression test: Since the repo favors TDD, a unit test constructing a cyclic ModelProvider (custom base chain looping back) would lock in the fix and document the scenario. Cycles only originate from custom code, so it''s awkward to set up but worthwhile.

  4. Description drift: The PR body lists a 4th change — "Emit new on explicit response conversion operators from ClientModel" — that isn''t present in the diff (3 files, none touching conversion operators). Worth trimming the description to match.

--generated by Copilot

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@JoshLove-msft

Copy link
Copy Markdown
Contributor

Added a regression test (BaseModelProviderCycleDoesNotRecurseInfinitely) in ModelProviderTests.cs to cover the base-model-provider cycle fix.

It wires two ModelProvider instances into a cycle (A → B → A) via an overridden BuildBaseModelProvider, then exercises FullConstructor, Constructors, and Fields — the base-traversal paths that previously recursed infinitely. Verified the test passes on this branch and that reverting the HasBaseModelProviderCycle guard aborts the run with a stack overflow, confirming it locks in the fix.

--generated by Copilot

@live1206 live1206 added this pull request to the merge queue Jun 23, 2026
Merged via the queue into main with commit e5403e9 Jun 23, 2026
29 checks passed
@live1206 live1206 deleted the live1206/fix-mtg-model-base-cycles branch June 23, 2026 03:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

emitter:client:csharp Issue for the C# client emitter: @typespec/http-client-csharp

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants